package com.jacksay.vikingfl.synchro
{
	import com.jacksay.vikingfl.stringtools.StringTools;
	
	import mx.core.UIComponent;
	
	
	public class VOPipe
	{
		
		// -----------------------------------------------------------------------------
		// host
		// -----------------------------------------------------------------------------
		/**
		 * Composant hébergeant l'affichage des données pour l'utilisateur.
		 * 
		 * @default null
		 * @author jacksay14
		 * @date 2009-12-14
		 */ 
		[Inspectable(defaultValue=null,verbose=1,category=Other)]
		public function get host () :UIComponent{
			return _host;
		}
		
		/**
		 * @private
		 */
		private var _host:UIComponent = null;
		
		/**
		 * @private
		 */
		public function set host( value:UIComponent ) :void {
			_host = value;
		}
		
		
		
		// -----------------------------------------------------------------------------
		// properties
		// -----------------------------------------------------------------------------
		/**
		 * Liste des propriétés de l'objet gérées par le composant.
		 * 
		 * @default null
		 * @author jacksay14
		 * @date 2009-12-14
		 */ 
		[Inspectable(defaultValue=null,verbose=1,category=Other)]
		[ArrayElementType("com.jacksay.vikingfl.synchro.VOPipeProperty")]
		public function get properties () :Array{
			return _properties;
		}
		
		/**
		 * @private
		 */
		private var _properties:Array = null;
		
		/**
		 * @private
		 */
		public function set properties( value:Array ) :void {
			_properties = value;
			
			// Création du pattern par defaut
			if( dataDisplayPattern == null && _properties != null ){
				var property:VOPipeProperty;
				var pattern:String = "";
				var sep:String = "";
				for each( property in _properties ){
					pattern = pattern.concat(sep, '%', property.dataNameInVO);
					sep = " ";
				}
				dataDisplayPattern = pattern;
			}
		}
		
		
		// -----------------------------------------------------------------------------
		// dataDisplayPattern
		// -----------------------------------------------------------------------------
		/**
		 * Pattern utilisé pour présenter les données à l'utilisateur dans le 
		 * modal de synchronisation. Si <code>null</code>, retourne une chaine 
		 * contenant les pipes surveillés séparés par un espace. Sinon retourne 
		 * la transcription du pattern. Le format du pattern est de type : 
		 * %property1 %property2 %propertyN
		 * 
		 * @default null
		 * @author jacksay14
		 * @date 2009-12-14
		 */ 
		[Inspectable(defaultValue=null,verbose=1,category=Other)]
		public function get dataDisplayPattern () :String{
			return _dataDisplayPattern;
		}
		
		/**
		 * @private
		 */
		private var _dataDisplayPattern:String = null;
		
		/**
		 * @private
		 */
		public function set dataDisplayPattern( value:String ) :void {
			if( value != _dataDisplayPattern && value != null )
				_dataDisplayPattern = value;
		}
		
		// -----------------------------------------------------------------------------
		// dataDisplayLabel
		// -----------------------------------------------------------------------------
		/**
		 * Nom de la donnée gérée par le host pour l'utilisateur.
		 * 
		 * @default null
		 * @author jacksay14
		 * @date 2009-12-14
		 */ 
		[Inspectable(defaultValue=null,verbose=1,category=Other)]
		public function get dataDisplayLabel () :String{
			return _dataDisplayLabel;
		}
		
		/**
		 * @private
		 */
		private var _dataDisplayLabel:String = null;
		
		/**
		 * @private
		 */
		public function set dataDisplayLabel( value:String ) :void {
			_dataDisplayLabel = value;
		}




		
		public function VOPipe( uiComponent:UIComponent, displayLabel:String, props:Array=null, patternDisplay:String=null)
		{
			host 				= uiComponent;
			dataDisplayLabel 	= displayLabel;
			properties 			= props;
			dataDisplayPattern 	= patternDisplay;
		}
		
		internal function initUserData() :void {
			var property:VOPipeProperty;
			for each( property in properties ){
				property.userDataUpdate(host[property.dataNameInView]);
			}
		}
		
		internal function synchronize( value:* ) :VOSynchonizePipeRepport {
			var property:VOPipeProperty;
			var synchroNeeded:int = 0;
			
			// On remplis le rapport
			// repport.user
			
			var dtInitial:Object 	= {};
			var dtUser:Object 		= {};
			var dtIncoming:Object 	= {};
			
			for each( property in properties ){
				property.setIncomingData( value[property.dataNameInVO] );
				synchroNeeded = Math.max(synchroNeeded, property.synchronize());
				
				// Construction des objets de données
				dtInitial[property.dataNameInVO] 	= property.initialData;
				dtUser[property.dataNameInVO] 		= property.userData;
				dtIncoming[property.dataNameInVO] 	= property.incomingData;
			}
			
			var repport:VOSynchonizePipeRepport = new VOSynchonizePipeRepport(this);
			repport.label = dataDisplayLabel;
			repport.user = StringTools.renderObjectWithPattern(dtUser, dataDisplayPattern);
			repport.incoming = StringTools.renderObjectWithPattern(dtIncoming, dataDisplayPattern);
			repport.initial = StringTools.renderObjectWithPattern(dtInitial, dataDisplayPattern);
			repport.response = synchroNeeded;
			
			if( synchroNeeded <= 2 ){
				for each( property in properties ){
					property.applySynchro(synchroNeeded);
				}
			}

			return repport;
		}
		
		internal function resolveSynchro( choix:int ) :void {
			var property:VOPipeProperty;
			// On remplis le rapport
			// repport.user
			for each( property in properties ){
				property.applySynchro(3, choix);
			}
		}

	}
}